#ifndef __NV_L40_GPU_H__
#define __NV_L40_GPU_H__

#include "interface/gpu.h"
#include "interface/gpu/power.h"
#include "interface/gpu/status.h"
#include "interface/processor.h"
#include "interface/pcie_card.h"
#include <mc/core/timer.h>
#include <mc/engine.h>
#include <smbus/smbus.h>
#include <smbus/smbus_postbox.h>

namespace dev {

class nv_l40_gpu : public mc::engine::object<nv_l40_gpu> {
public:
    MC_OBJECT(nv_l40_gpu, "GraphicsController", "GraphicsController/${Id}",
              (Processor)(Gpu)(Gpu_Power)(Gpu_Status)(PCIeCard))

    nv_l40_gpu()  = default;
    ~nv_l40_gpu() = default;

    bool start();
    bool stop();
    bool init(mc::mutable_dict& csr_object, const mc::dict& connector);

    bool reset_default_properties();

    Processor  m_processor;
    Gpu        m_gpu;
    Gpu_Power  m_gpu_power;
    Gpu_Status m_gpu_status;
    PCIeCard   m_pcie_card;

private:
    bool init_smbus_postbox();
    void register_ref_chip();
    bool _card_builddate            = false;
    bool _infoRomVersion            = false;
    bool _uuid                      = false;
    bool _pcie_firmware_version     = false;
    bool _pcie_serialnumber         = false;
    bool _pcie_partnumber           = false;
    bool _gpu_partnumber            = false;

    mc::shared_ptr<mc::engine::ref_object> m_ref_chip;
    mc::shared_ptr<smbus>                  m_smbus_obj;
    std::shared_ptr<SMBusPostboxProtocol>  m_smbus_postbox;
    mc::core::timer*                       m_postbox_timer;
};

} // namespace dev

#endif // __nv_l40_GPU_H__